# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.930.52.3+1.930.37.31 -> 1.930.53.1 # Makefile 1.190.1.15 -> 1.207 # drivers/net/tg3.c 1.56.1.2 -> 1.61.1.1 # drivers/net/tg3.h 1.25.1.1 -> 1.26.1.1 # include/linux/highmem.h 1.10.1.1 -> 1.11.1.1 # drivers/char/Makefile 1.27.1.4 -> 1.30.1.1 # diff -Nru a/Makefile b/Makefile --- a/Makefile Wed Oct 8 09:08:33 2003 +++ b/Makefile Wed Oct 8 09:08:33 2003 @@ -90,6 +90,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -fno-strict-aliasing -fno-common +CFLAGS += -g ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif @@ -300,8 +301,7 @@ $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks - $(MAKE) -C scripts kconfig.tk - wish -f scripts/kconfig.tk + @echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***" menuconfig: include/linux/version.h symlinks $(MAKE) -C scripts/lxdialog all diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile --- a/drivers/char/Makefile Wed Oct 8 09:08:33 2003 +++ b/drivers/char/Makefile Wed Oct 8 09:08:33 2003 @@ -182,6 +182,7 @@ obj-$(CONFIG_HIL) += hp_keyb.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o +obj-$(CONFIG_HP_SIMSERIAL) += simserial.o obj-$(CONFIG_ROCKETPORT) += rocket.o obj-$(CONFIG_MOXA_SMARTIO) += mxser.o obj-$(CONFIG_MOXA_INTELLIO) += moxa.o diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Wed Oct 8 09:08:33 2003 +++ b/drivers/net/tg3.c Wed Oct 8 09:08:33 2003 @@ -50,8 +50,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4" -#define DRV_MODULE_RELDATE "Feb 1, 2003" +#define DRV_MODULE_VERSION "1.4c" +#define DRV_MODULE_RELDATE "Feb 18, 2003" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -210,6 +210,12 @@ tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); } +static inline void tg3_cond_int(struct tg3 *tp) +{ + if (tp->hw_status->status & SD_STATUS_UPDATED) + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); +} + static void tg3_enable_ints(struct tg3 *tp) { tw32(TG3PCI_MISC_HOST_CTRL, @@ -217,9 +223,55 @@ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); - if (tp->hw_status->status & SD_STATUS_UPDATED) - tw32(GRC_LOCAL_CTRL, - tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); + tg3_cond_int(tp); +} + +/* these netif_xxx funcs should be moved into generic net layer */ +static void netif_poll_disable(struct net_device *dev) +{ + while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + } +} + +static inline void netif_poll_enable(struct net_device *dev) +{ + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + +/* same as netif_rx_complete, except that local_irq_save(flags) + * has already been issued + */ +static inline void __netif_rx_complete(struct net_device *dev) +{ + if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); + list_del(&dev->poll_list); + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + +static inline void netif_tx_disable(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); + netif_stop_queue(dev); + spin_unlock_bh(&dev->xmit_lock); +} + +static inline void tg3_netif_stop(struct tg3 *tp) +{ + netif_poll_disable(tp->dev); + netif_tx_disable(tp->dev); +} + +static inline void tg3_netif_start(struct tg3 *tp) +{ + netif_wake_queue(tp->dev); + /* NOTE: unconditional netif_wake_queue is only appropriate + * so long as all callers are assured to have free tx slots + * (such as after tg3_init_hw) + */ + netif_poll_enable(tp->dev); + tg3_cond_int(tp); } static void tg3_switch_clocks(struct tg3 *tp) @@ -381,7 +433,6 @@ } static int tg3_setup_phy(struct tg3 *); -static int tg3_halt(struct tg3 *); static int tg3_set_power_state(struct tg3 *tp, int state) { @@ -452,8 +503,6 @@ tg3_setup_phy(tp); } - tg3_halt(tp); - pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { @@ -2038,7 +2087,12 @@ spin_unlock(&tp->tx_lock); } - /* run RX thread, within the bounds set by NAPI */ + spin_unlock_irqrestore(&tp->lock, flags); + + /* run RX thread, within the bounds set by NAPI. + * All RX "locking" is done by ensuring outside + * code synchronizes with dev->poll() + */ done = 1; if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { int orig_budget = *budget; @@ -2058,12 +2112,12 @@ /* if no more work, tell net stack and NIC we're done */ if (done) { - netif_rx_complete(netdev); + spin_lock_irqsave(&tp->lock, flags); + __netif_rx_complete(netdev); tg3_enable_ints(tp); + spin_unlock_irqrestore(&tp->lock, flags); } - spin_unlock_irqrestore(&tp->lock, flags); - return (done ? 0 : 1); } @@ -2130,17 +2184,21 @@ static void tg3_init_rings(struct tg3 *); static int tg3_init_hw(struct tg3 *); +static int tg3_halt(struct tg3 *); -static void tg3_tx_timeout(struct net_device *dev) +static void tg3_reset_task(void *_data) { - struct tg3 *tp = dev->priv; + struct tg3 *tp = _data; + unsigned int restart_timer; - printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", - dev->name); + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); + restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; + tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; + tg3_halt(tp); tg3_init_rings(tp); tg3_init_hw(tp); @@ -2148,7 +2206,20 @@ spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - netif_wake_queue(dev); + tg3_netif_start(tp); + + if (restart_timer) + mod_timer(&tp->timer, jiffies + 1); +} + +static void tg3_tx_timeout(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + + printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", + dev->name); + + schedule_task(&tp->reset_task); } #if !PCI_DMA_BUS_IS_PHYS @@ -2654,6 +2725,7 @@ return 0; } + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -2666,6 +2738,7 @@ spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); return 0; } @@ -3041,6 +3114,7 @@ static void tg3_chip_reset(struct tg3 *tp) { u32 val; + u32 flags_save; /* Force NVRAM to settle. * This deals with a chip bug which can result in EEPROM @@ -3057,8 +3131,21 @@ } } + /* + * We must avoid the readl() that normally takes place. + * It locks machines, causes machine checks, and other + * fun things. So, temporarily disable the 5701 + * hardware workaround, while we do the reset. + */ + flags_save = tp->tg3_flags; + tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; + + /* do the reset */ tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET); + /* restore 5701 hardware bug workaround flag */ + tp->tg3_flags = flags_save; + /* Flush PCI posted writes. The normal MMIO registers * are inaccessible at this time so this is the only * way to make this reliably. I tried to use indirect @@ -4360,9 +4447,11 @@ } if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - tg3_halt(tp); - tg3_init_rings(tp); - tg3_init_hw(tp); + tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; + spin_unlock(&tp->tx_lock); + spin_unlock_irqrestore(&tp->lock, flags); + schedule_task(&tp->reset_task); + return; } /* This part only runs once per second. */ @@ -4493,8 +4582,6 @@ return err; } - netif_start_queue(dev); - spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -4503,6 +4590,8 @@ spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + netif_start_queue(dev); + return 0; } @@ -5268,6 +5357,7 @@ (ering.tx_pending > TG3_TX_RING_SIZE - 1)) return -EINVAL; + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -5281,6 +5371,7 @@ netif_wake_queue(tp->dev); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); return 0; } @@ -5303,6 +5394,7 @@ if (copy_from_user(&epause, useraddr, sizeof(epause))) return -EFAULT; + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); if (epause.autoneg) @@ -5322,6 +5414,7 @@ tg3_init_hw(tp); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); return 0; } @@ -6671,6 +6764,7 @@ spin_lock_init(&tp->lock); spin_lock_init(&tp->tx_lock); spin_lock_init(&tp->indirect_lock); + PREPARE_TQUEUE(&tp->reset_task, tg3_reset_task, tp); tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len); if (tp->regs == 0UL) { @@ -6801,6 +6895,8 @@ if (!netif_running(dev)) return 0; + tg3_netif_stop(tp); + spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); tg3_disable_ints(tp); @@ -6827,6 +6923,7 @@ spin_unlock_irq(&tp->lock); netif_device_attach(dev); + tg3_netif_start(tp); } return err; @@ -6856,6 +6953,8 @@ spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + + tg3_netif_start(tp); return 0; } diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h --- a/drivers/net/tg3.h Wed Oct 8 09:08:33 2003 +++ b/drivers/net/tg3.h Wed Oct 8 09:08:33 2003 @@ -1795,7 +1795,6 @@ #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 -#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 diff -Nru a/include/linux/highmem.h b/include/linux/highmem.h --- a/include/linux/highmem.h Wed Oct 8 09:08:33 2003 +++ b/include/linux/highmem.h Wed Oct 8 09:08:33 2003 @@ -84,7 +84,7 @@ static inline void clear_user_highpage(struct page *page, unsigned long vaddr) { void *addr = kmap_atomic(page, KM_USER0); - clear_user_page(addr, vaddr); + clear_user_page(addr, vaddr, page); kunmap_atomic(addr, KM_USER0); } @@ -116,7 +116,7 @@ vfrom = kmap_atomic(from, KM_USER0); vto = kmap_atomic(to, KM_USER1); - copy_user_page(vto, vfrom, vaddr); + copy_user_page(vto, vfrom, vaddr, to); kunmap_atomic(vfrom, KM_USER0); kunmap_atomic(vto, KM_USER1); }